﻿//读string数组做法不行
/*#include <stdio.h>
#include <string.h>
#include<iostream>
#include<stack>

using namespace std;
int comp(string a) {
	int level;
	if (a == "(")
	{
		level = 3;
	}
	if (a == "+" || a == "-")
	{
		level = 1;
	}
	if (a == "*" || a == "/")
	{
		level = 2;
	}
	if (a == ")")
	{
		level = -1;
	}
	return level;
}
int main() {
	
	ios::sync_with_stdio(false);
	cin.tie(0);

	string a[1000];
	stack <string>n;
	stack <string>f;
	char c;
	int g;
	int L;
	string o;
	string b;
	int wrong = 0;//单数字表达式在下方ERROR通行证
	int wrong2 = 0;//单数字表达式在下方ERROR通行证
	int j;
	int t = 0, r = 0;
	int i;

	if (a[i][0] != '+' && a[i][0] != '-' && a[i][0] != '*' && a[i][0] != '/' && a[i][0] != '0' && a[i][0] != '1' && a[i][0] != '2' && a[i][0] != '3' && a[i][0] != '4' && a[i][0] != '5' && a[i][0] != '6' && a[i][0] != '7' && a[i][0] != '8' && a[i][0] != '9' && a[i][0] != '(' && a[i][0] != ')')
		{
			r = i;
			break;
		}
	while (1)
	{
		cin >> a[r];
		c = getchar();
		if (c == '\n')//if (r == 7)会对地一个测试点

		{
			break;
		}
		r++;
	}
	
	if (r > 0) //+5和-5都是一个字符串啊
	{
		for (i=0; i <r; i++)//这里将i>=0改成i>=-1，因为i=0时一定会执行下面的一个if的操作，把a[0]压入栈内
		{//再看下一个字符数组之前，先检查自身是否符合运算条件
				if (!(a[i] == "+" || a[i] == "-" || a[i] == "*" || a[i] == "/" || a[i] == "(" || a[i] == ")"))//不足元素做运算
				{
					cout << a[i]<<" ";
				}
				else//做运算，且保留原地，即i在此轮循环中保持不变
			{//因为n.top()是装进栈里面的数，所以你不知道是char还是double
				if (f.empty())
				{
					f.push(a[i]);
				}
				else
				{
					if (a[i] == ")") {
						L = 0;
						while (f.top()!="(") {
							cout << f.top() << " ";
							f.pop();

						}
						f.pop();//pop (;
					}
					else {
						if ((comp(a[i]) > comp(f.top()))||L==1)//当前符号优先级小于栈顶符号就入栈
						{
							if (a[i] == "(") {
								L = 1;
							}
							f.push(a[i]);
						}
						else
						{
							while (!f.empty()) {
								if (f.top() != "(") {
									cout << f.top() << " ";
								}
								f.pop();

							}
							f.push(a[i]);
						}
					}
				}
			}
		}
	}
	else
	{
		if ((a[0][0] == '+' || a[0][0] == '-') && !(a[0][1] == '+' || a[0][1] == '-'))
		{

			wrong2 = 1;
		}
		else
		{
			cout << "ERROR";
		}
	}
	if (wrong2 == 1)
	{
		cout<<a[0];
	}
	else
	{
		if (wrong != 1)
		{
			while (!f.empty()) {
				if (f.top() != "(") {
					cout << f.top() ;
					if (f.size()!= 1)
					{
						cout << " ";
					}
				}
				f.pop();

			}
		}
		else
		{

			cout << "ERROR";

		}
	}
	*/
/*
#include <stdio.h>
#include <string.h>
#include<iostream>
#include<stack>

using namespace std;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	string a;
	int i;
	char c;
	int r = 0;
	string s[99];//代表储存运算符号的栈
	int top = -1;
	i = 0;
	int k;
	int flag = 0;//标记，看是不是第一个数字，是直接打出，不是先打出空格
	getline(cin, a)
		for (i = 0; i < r; i++) {
			if (a[i] >= "0" && a[i] <= "9")
			{//如果是数字，直接打印出数字，包括多位的数字和小数
				int j = i;//保存开头
				while ((a[i] >= "0" && a[i] <= "9") || a[i] == ".")i++;//找到第一个不为数字的字符
				i--;//回到最后一个数字字符上，因为for循环最后i++；
				int k;
				if (!flag || (a[j - 1] == "-" && (a[j - 2] == "(" || a[j - 2] == "+" || a[j - 2] == "-" || a[j - 2] == "*" || a[j - 2] == "/")) || (a[j - 1] == "-" && j - 1 == 0) || (a[j - 1] == "+" && j - 1 == 0) || (a[j - 1] == "+" && (a[j - 2] == "(" || a[j - 2] == "+" || a[j - 2] == "-" || a[j - 2] == "*" || a[j - 2] == "/")));//负数或者第一个数字，数字前不打空格，否则会和负号分开
				else printf(" ");//这里是j千万别写成i，j记录的数字的开头
				flag = 1;
				for (k = j; k <= i; k++)cout << a[k];//输出
			}
			else {//如果是运算符
				if (i == 0 && (a[i][0] == '-' || a[i][0] == '+')) {//开始的符号
					if (a[i][0] == '-')cout << a[i] << " ";
					continue;
				}
				if (i == 1 && a[i - 1][0] == '(' && (a[i][1] == '-' || a[i][1] == '+')) {//如果第一个是括号然后又是正负，坑死了这里，打死没想到
					if (a[i][1] == '-')cout << a[i] << " ";
					continue;
				}
				if (top == -1) {//如果栈为空，直接把运算符加进去
					s[++top] = a[i];
				}
				else {//入队原则：如果当前符号比栈顶优先级大，入栈，否则pop输出栈顶，再继续比较，直到比栈顶优先级大再入栈
					if (a[i] == "+" || a[i] == "-") {//如果是加减号
						if (a[i] == "-" && a[i - 1] == "(") {//中间的负号
							printf(" -");
							continue;
						}
						if (a[i] == "+" && a[i - 1] == "(") {//中加的加号
							printf(" ");//如果有正号，不输出
							continue;
						}
						if ((a[i] == "+" || a[i] == " -") && (a[i - 1] == "+" || a[i - 1] == " -" || a[i - 1] == "*" || a[i - 1] == "/")) {
							if (a[i] == " -")cout << a[i] << " ";
							if (a[i] == "+")printf(" ");//正号不输出
							continue;
						}
						//if(s[top]=='*'||s[top]=='/'){//首先比较时第一个一定要比当前优先级大才开始出队。否则只能入队
						while ((top != -1) && (s[top] == "+" || s[top] == " -" || s[top] == "/" || s[top] == "*")) {//比较如果栈内元素优先级大于当前符号。先出栈，直到比它大
							cout << s[top--] << " ";
						}
						//}
						s[++top] = a[i];//判断并出栈之后这个符号就可以入栈了
					}
					else if (a[i] == "*" || a[i] == "/") {//如果是乘除号
						while ((top != -1) && (s[top] == "*" || s[top] == "/")) {//因为乘除号是最高优先级，所以只有相等时需要出栈
							cout << s[top--] << " ";
						}
						s[++top] = a[i];
					}
					else if (a[i] == "(") {//左括号的时候比较特殊，直接入栈
						s[++top] = a[i];
					}
					else if (a[i] == ")") {//右括号的时候直接出栈到左括号
						while ((top != -1) && s[top] != "(")
							cout << s[top--] << " ";
						top--;//把左括号pop掉
					}
				}
			}
		}
	cout << " ";
	//结束后栈内剩下的符号一次出栈输出即可
	while (top != -1) {
		if (s[top] != "(" && s[top] != ")")
		{
			cout << s[top];
			if (top - 1 != -1) {
				cout << " ";
			}

		}
		top--;
	}

}*/
	//这是一道异常的题目，只有getline才能读包括空格而不能通过读字符串数组
#include <stdio.h>
#include <string>
#include<iostream>
using namespace std;
int main() {
	string a;//输入字符串
	char s[300];//代表储存运算符号的栈
	int top = -1;
	getline(cin,(a));
	
	int i;
	int flag = 0;//标记，看是不是第一个数字，是直接打出，不是先打出空格
	for (i = 0; a[i]; i++) {
		if (a[i] != ' ') {
			if (a[i] >= '0' && a[i] <= '9') {//如果是数字，直接打印出数字，包括多位的数字和小数
				int j = i;//保存开头
				while ((a[i] >= '0' && a[i] <= '9') || a[i] == '.')i++;//找到第一个不为数字的字符
				i--;//回到最后一个数字字符上，因为for循环最后i++；
				int k;
				if (!flag || (a[j - 1] == '-' && (a[j - 2] == '(' || a[j - 2] == '+' || a[j - 2] == '-' || a[j - 2] == '*' || a[j - 2] == '/')) || (a[j - 1] == '-' && j - 1 == 0) || (a[j - 1] == '+' && j - 1 == 0) || (a[j - 1] == '+' && (a[j - 2] == '(' || a[j - 2] == '+' || a[j - 2] == '-' || a[j - 2] == '*' || a[j - 2] == '/')));//负数或者第一个数字，数字前不打空格，否则会和负号分开
				else printf(" ");//这里是j千万别写成i，j记录的数字的开头
				flag = 1;
				for (k = j; k <= i; k++)printf("%c", a[k]);//输出
			}
			else {//如果是运算符
				if (i == 0 && (a[i] == '-' || a[i] == '+')) {//开始的符号
					if (a[i] == '-')printf("%c", a[i]);
					continue;
				}
				if (i == 1 && a[i - 1] == '(' && (a[i] == '-' || a[i] == '+')) {//如果第一个是括号然后又是正负，坑死了这里，打死没想到
					if (a[i] == '-')printf("%c", a[i]);
					continue;
				}
				if (top == -1) {//如果栈为空，直接把运算符加进去
					s[++top] = a[i];
				}
				else {//入队原则：如果当前符号比栈顶优先级大，入栈，否则pop输出栈顶，再继续比较，直到比栈顶优先级大再入栈
					if (a[i] == '+' || a[i] == '-') {//如果是加减号
						if (a[i] == '-' && a[i - 1] == '(') {//中间的负号
							printf(" -");
							continue;
						}
						if (a[i] == '+' && a[i - 1] == '(') {//中加的加号
							printf(" ");//如果有正号，不输出
							continue;
						}
						if ((a[i] == '+' || a[i] == '-') && (a[i - 1] == '+' || a[i - 1] == '-' || a[i - 1] == '*' || a[i - 1] == '/')) {
							if (a[i] == '-')printf(" %c", a[i]);
							if (a[i] == '+')printf(" ");//正号不输出
							continue;
						}
						//if(s[top]=='*'||s[top]=='/'){//首先比较时第一个一定要比当前优先级大才开始出队。否则只能入队
						while ((top != -1) && (s[top] == '+' || s[top] == '-' || s[top] == '/' || s[top] == '*')) {//比较如果栈内元素优先级大于当前符号。先出栈，直到比它大
							printf(" %c", s[top--]);
						}
						//}
						s[++top] = a[i];//判断并出栈之后这个符号就可以入栈了
					}
					else if (a[i] == '*' || a[i] == '/') {//如果是乘除号
						while ((top != -1) && (s[top] == '*' || s[top] == '/')) {//因为乘除号是最高优先级，所以只有相等时需要出栈
							printf(" %c", s[top--]);
						}
						s[++top] = a[i];
					}
					else if (a[i] == '(') {//左括号的时候比较特殊，直接入栈
						s[++top] = a[i];
					}
					else if (a[i] == ')') {//右括号的时候直接出栈到左括号
						while ((top != -1) && s[top] != '(')
							printf(" %c", s[top--]);
						top--;//把左括号pop掉
					}
				}
			}
		}
		else {
			continue;
		}
	}
	//结束后栈内剩下的符号一次出栈输出即可
	while (top != -1) {
		printf(" %c", s[top--]);
	}
	
}
